<template>
	<view class="tree">
		<view class="tree-meta">
			<scroll-view scroll-with-animation :show-scrollbar="false" scroll-x class="tree-meta-breadcrumb"
				:scroll-into-view="intoView">
        <text @click="clearBreadCrumb">首级</text>
				<text :id="'breadCrumb' + item[props.value]" v-for="(item,index) in breadCrumb" :key="index"
					@click="clickBreadCrumb(item)">{{item.title}}</text>
			</scroll-view>
		</view>
		<scroll-view scroll-y class="tree-list">
			<view class="tree-list-item" v-for="(item,index) in list" :key="index" v-if="list.length > 0">
				<checkbox-group @change="selectRow($event, item)">
					<checkbox :value="item[props.value]" :checked="isCheck(item[props.value])" style="transform:scale(0.7)" />
				</checkbox-group>
				<view class="tree-list-info" @click="handleClick(item)">
					<view>
						{{ item[props.label] }}
					</view>
				</view>
				<uni-icons type="forward" size="20" v-if="item[props.children] && item[props.children].length > 0"></uni-icons>
			</view>
			<view class="nodata" style="padding-top:40rpx;" v-if="list.length == 0">
				<view class="nodata-text">暂无数据</view>
			</view>
		</scroll-view>
		<view class="tree-box" style="padding-bottom:240rpx">
			<view class="tree-box-info" @click="chooseVisible = !chooseVisible">
				<template v-if="chooseVisible">
					收起 <uni-icons type="bottom" size="20"></uni-icons>
				</template>
				<template v-else>
					已选中（{{ selectList.length }}） <uni-icons type="top" size="20"></uni-icons>
				</template>
			</view>
			<view class="tree-box-btn success" @click="confirm">确认</view>
		</view>
		<view class="tree-choose" :class="{on:chooseVisible}">
			<view class="tree-choose-mask" @click="chooseVisible = false"></view>
			<view class="tree-choose-inner">
				<view class="tree-choose-title">
					<view>已选中（{{ selectList.length }}）</view>
					<view @click="clearSelect">清空</view>
				</view>
				<view class="tree-list" v-if="selectList.length > 0">
					<view class="tree-list-item" v-for="(item,index) in selectList" :key="index">
						<view class="tree-list-info">
							<view>{{ item[props.label] }}</view>
						</view>
						<uni-icons type="closeempty" size="20" @click="removeSelectRow(index)"></uni-icons>
					</view>
				</view>
				<view class="nodata" style="padding-top:40rpx;" v-else>
					<view class="nodata-text">暂无选中数据</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			// 回显值
			value: {
				type: Array,
				default: () => []
			},
			// 树数据
			treeData: {
				type: Array,
				default: () => []
			},
			// 树字段值
			props: {
				type: Object,
				default: () => ({
					label: "name",
					value: "id",
					children: "children"
				})
			},
      drawerStatus: {
        type: String
      },
      ruleFormData: {
        type: String
      }
		},
		data() {
			return {
				// 面包屑
				breadCrumb: [],
				// 设置面包屑位置
				intoView: "",
				// 当前展示数据
				list: [],
				// 选中列表
				selectList: [],
				// 是否显示已选地区列表
				chooseVisible: false
			}
		},
		watch: {
			// 异步请求回显
      value: {
        handler(newVal, oldVal) {
					const valueData = newVal.map(item => item[this.props.value])
					this.getInitData(valueData, this.treeData)
        },
        deep: true
      },
      treeData: {
        handler(newVal, oldVal) {
          this.list = newVal
        },
        deep: true
      },
      drawerStatus(newVal, oldVal) {
        if (newVal === 'close') {
          this.breadCrumb = []
          this.list = this.treeData
          const formData = this.ruleFormData ? this.ruleFormData.split(',') : ''
          this.selectList = []
          if (!formData) return
					this.getInitData(formData, this.treeData)
        }
      }
		},
    created() {
      this.list = this.treeData
    },
		methods: {
			getInitData(data, options) {
				options.forEach(item => {
					if (data.includes(item[this.props.value]) || data.includes(item[this.props.value].toString())) {
						this.selectList.push(item)
					}
					if (item.children && item.children.length) {
						this.getInitData(data, item.children)
					}
				})
			},
			// 添加面包屑
			addBreadCrumb(row) {
				this.breadCrumb.push({
					id: row[this.props.value],
					title: row[this.props.label],
					list: row[this.props.children]
				});
				this.autoLower(row[this.props.value]);
			},
			// 点击面包屑
			clickBreadCrumb(row) {
				this.autoLower(row[this.props.value]);
				const index = this.breadCrumb.findIndex(item => item[this.props.value] == row[this.props.value]);
				// 删除点击索引后的所有数据
				this.breadCrumb.splice(index + 1, this.breadCrumb.length - 1);
				this.list = this.breadCrumb[index].list;
			},
			// 清空面包屑
			clearBreadCrumb() {
				this.breadCrumb = [];
				this.list = this.treeData;
			},
			// 面包屑自动靠右
			autoLower(id) {
				this.$nextTick(() => {
					this.intoView = `breadCrumb${id}`
				});
			},
			// 点击列表项
			handleClick(row) {
				// 没有子级则不需要执行操作
				if (!(row[this.props.children] && row[this.props.children].length)) return;
				this.addBreadCrumb(row);
				this.list = row[this.props.children];
			},
			// 判断列表项是否选中
			isCheck(id) {
				return this.selectList.findIndex(item => item[this.props.value] === id) > -1;
			},
			// 选中
			selectRow(e, row) {
				// 选中
				if (e.detail.value.length > 0) {
					this.selectList.push(row);
				}
				// 取消选中
				else {
					const index = this.list.findIndex(item => item[this.props.value] == row[this.props.value]);
					this.selectList.splice(index, 1);
				}
			},
			// 删除选中
			removeSelectRow(index) {
				this.selectList.splice(index, 1);
			},
			// 清空选中
			clearSelect() {
				uni.showModal({
					title: "提示",
					content: "确认清空已选中数据吗？",
					success: (res) => {
						if (res.confirm) {
							this.selectList = []
						}
					}
				})
			},
			// 点击确认
			confirm() {
				const selectIds = this.selectList.map(item => item[this.props.value]).join(",");
				const selectNames = this.selectList.map(item => item[this.props.label]).join(",");
				const result = {
					selectIds,
					selectNames,
					selectList: this.selectList
				}
				this.$emit("confirm", result)
			}
		}
	}
</script>

<style lang="less">
	.tree {
    width: 100%;
		height: 100vh;
		display: flex;
		flex-direction: column;
		background: #FFF;

		&-meta {
			background: #FFF;
			display: flex;
			line-height: 96rpx;
			margin-bottom: 20rpx;

			&-breadcrumb {
				flex: 1;
				padding: 0 40rpx;
				white-space: nowrap;
				overflow: auto;

				text {
					color: #8c8c8c;

					&::after {
						font-family: "uniicons" !important;
						content: "\e6ba";
						margin: 0 16rpx;
					}

					&:last-child {
						color: #000;

						&::after {
							display: none;
						}
					}
				}
			}
		}

		// 主体区域
		&-list {
			flex: 1;
			overflow: auto;
			background: #fafafa;

			&-item {
				display: flex;
				align-items: center;
				padding: 24rpx 40rpx;
				border-bottom: 1px solid #e6e6e6;

				i {
					font-size: 40rpx;
					color: #666;
				}

			}

			&-info {
				flex: 1;
				display: flex;
				align-items: center;

				uni-checkbox {
					margin-right: 20rpx;
				}

				image {
					width: 64rpx;
					height: 64rpx;
					margin-right: 16rpx;
				}

				view {
					font-size: 32rpx;

					&.red {
						color: #dd524d;
					}
				}
			}
		}

		// 结果集
		&-box {
			position: relative;
			z-index: 3;
			border-top: 1px solid #e6e6e6;
			background: #fff;
			display: flex;
			font-size: 36rpx;

			&-info {
				flex: 1;
				display: flex;
				justify-content: center;
				align-items: center;
				line-height: 116rpx;

				text {
					color: #0b3f35;
					margin: 0 16rpx;
				}
			}

			&-btn {
				height: 116rpx;
				line-height: 116rpx;
				width: 216rpx;
				text-align: center;

				&.success {
					background: #0b3f35;
					color: #fff;
				}

				&.danger {
					background: #dd524d;
					color: #fff;
				}
			}
		}

		// 当前选中
		&-choose {
			position: fixed;
			left: 0;
			right: 0;
			top: 0;
			bottom: 0;
			z-index: 2;
			visibility: hidden;

			&.on {
				visibility: initial;

				.tree-choose-mask {
					opacity: 1;
				}

				.tree-choose-inner {
					bottom: 116rpx;
				}
			}

			&-mask {
				opacity: 0;
				width: 100%;
				height: 100%;
				background: rgba(0, 0, 0, 0.7);
				transition: all .3s ease;
			}

			&-inner {
				position: absolute;
				bottom: -820rpx;
				width: 100%;
				background: #fff;
				height: 700rpx;
				display: flex;
				flex-direction: column;
				transition: all .3s ease;
			}

			&-title {
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 0 40rpx;
				line-height: 96rpx;
				border-bottom: 1px solid #e3e3e3;

				view {
					font-size: 32rpx;
					color: #8c8c8c;
				}

				text {
					color: #004986;
				}
			}

			&-content {}
		}
	}

	.nodata {
		padding: 30rpx 0;
		text-align: center;

		image {
			width: 500rpx;
		}

		&-text {
			font-size: 28rpx;
			color: #999;
		}
	}
</style>
